/* eslint-disable */
(function(_global) {
	const ua = navigator.userAgent; //获取判断用的对象
	const isAndroid = ua.indexOf('Android') > -1 || ua.indexOf('Adr') > -1 || ua.indexOf('android') > -
		1 //android
	const isIOS = !!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
	const isWechat = /MicroMessenger/i.test(ua) && !/wxwork/i.test(ua) // 微信浏览器环境
	const isInWechatWV = ua.toLowerCase().indexOf('miniprogram') > -1 // 小程序webview环境
	const isInSuperappWV = ua.indexOf('SuperApp') > -1 // 超级app环境

	let debug = true
	let bridge = null
	let queue = []
	let wxParams = {}
	let failText = '仅支持超级app/微信小程序内嵌H5使用'

	/**
	 * sdk加载状态
	 * uninitialized 未初始化
	 * initializing 正在初始化
	 * initialized 初始化完成
	 * failed 加载失败 (当前环境不支持)
	 */
	let SDK_LOAD_STATUS = 'uninitialized'

	function setupWebViewJavascriptBridgeIOS(callback) {

		if (window.WebViewJavascriptBridge) {
			return callback(WebViewJavascriptBridge);
		}
		if (window.WVJBCallbacks) {
			return window.WVJBCallbacks.push(callback);
		}
		window.WVJBCallbacks = [callback];
		let WVJBIframe = document.createElement('iframe');
		WVJBIframe.style.display = 'none';
		WVJBIframe.src = 'https://__bridge_loaded__';
		document.documentElement.appendChild(WVJBIframe);
		setTimeout(function() {
			document.documentElement.removeChild(WVJBIframe)
		}, 0)
	}

	function setupWebViewJavascriptBridgeAZ(callback) {
		if (window.WebViewJavascriptBridge) {
			return callback(WebViewJavascriptBridge);
		}
		if (window.WVJBCallbacks) {
			return window.WVJBCallbacks.push(callback);
		}
		window.WVJBCallbacks = [callback];
		let WVJBIframe = document.createElement('iframe');
		WVJBIframe.style.display = 'none';
		//这里最新IOS版是 https的scheme，真实环境下 需要判断iOS和Android，做下区分。
		//WVJBIframe.src = 'wvjbscheme://BRIDGE_LOADED';
		WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
		document.documentElement.appendChild(WVJBIframe);
		setTimeout(function() {
			document.documentElement.removeChild(WVJBIframe)
		}, 0);
	}

	function loadScript(url, callback) {
		let script = document.createElement('script')
		script.onload = function() {
			callback()
		}
		script.src = url
		document.head.appendChild(script)
	}

	let vconsole
	/**
	 * vconsole debuger
	 */
	function loadDebuger() {
		if (vconsole) return
		loadScript("https://cdn.bootcdn.net/ajax/libs/vConsole/3.4.1/vconsole.min.js", () => {
			vconsole = new VConsole()
		})
	}

	function log() {
		debug && console.log.apply(null, arguments)
	}

	/**
	 * 初始化微信jssdk
	 * @param {Function} success 
	 * @param {Function} fail 
	 */
	function initWXJSSDK(opt = {}) {
		window.wx = null
		loadScript("https://res.wx.qq.com/open/js/jweixin-1.3.2.js", () => {
			if (!wxParams.jsApiList || !wxParams.portalServiceUrl) {
				opt.fail && opt.fail('门户接口域名未配置')
			}
			
			getJsSign(res => {
				if (!res) {
					opt.fail && opt.fail('JSSDK配置接口请求错误')
					return
				}
				
				try {
					const data = res.data
					wx.config({
						debug: wxParams.debug ||
						false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来，若要查看传入的参数，可以在pc端打开，参数信息会通过log打出，仅在pc端时才会打印。
						appId: data.appid, // 必填，公众号的唯一标识
						timestamp: data.timestamp, // 必填，生成签名的时间戳
						nonceStr: data.nonceStr, // 必填，生成签名的随机串
						signature: data.signature, // 必填，签名
						jsApiList: wxParams.jsApiList // 必填，需要使用的JS接口列表
					})
					
					wx.ready(() => {
						opt.success && opt.success()
					})
					
					wx.error(e => {
						opt.fail && opt.fail('JSSDK校验失败: ' + e.errMsg)
					})
				} catch(err){
					opt.fail && opt.fail('JSSDK配置接口请求错误')
				}
			})
		})
	}

	/**
	 * 获取签名配置
	 * @param {Function} callback 
	 */
	function getJsSign(callback) {
		const xhr = new XMLHttpRequest()
		xhr.onreadystatechange = () => {
			if (xhr.readyState === 4) { 
				if(xhr.status === 200) { // 处理响应结果
					callback(JSON.parse(xhr.response))
				}else{
					callback(false)
				}
			}
		}
		
		xhr.onerror = (e) => {
			callback(false)
		};

		const url = wxParams.portalServiceUrl + '/v1/wechat/getWechatJSSDK?url=' + encodeURIComponent(window
			.location.href.split('#')[0])
		try {
			xhr.open("GET", url);
			xhr.responseType = "application/json";
			xhr.send();
		} catch (e) {
			setTimeout(function() {
				callback(false)
			}, 0);
		}
	}

	/**
	 * jsBridge初始化
	 * @param { Boolean } execQueue 是否执行被阻塞的任务
	 */
	function bridgeInit(execQueue, fail) {

		SDK_LOAD_STATUS = 'initializing'

		const initiated = function(res) {
			SDK_LOAD_STATUS = res ? 'initialized' : 'failed'
			if(res) {
				execQueue && queue.forEach(v => v()) // 执行被阻塞的任务
			}
		}

		if (isInWechatWV) { // 微信浏览器环境
			// 初始化微信jssdk
			initWXJSSDK({
				success() {
					bridge = wx
					initiated(true)
				},
				fail(e) {
                    bridge = wx
					initiated(false)
					fail && fail(e)
				}
			})
		} else if (isInSuperappWV) { // superapp环境
			if (isIOS) {
				log('判断出是ios');
				setupWebViewJavascriptBridgeIOS(function(webViewJavascriptBridge) {
					log('生成bridgeios', webViewJavascriptBridge);
					bridge = webViewJavascriptBridge; //保存起来以后别的页面用
					initiated(true)
				});
			} else if (isAndroid) {
				//安卓调用
				log('判断出是Android');
				setupWebViewJavascriptBridgeAZ(function(webViewJavascriptBridge) {
					// 是个异步的方法，不能直接return，（直接return的是里面那个方法）所以需要全局变量接收
					log('生成bridgeAndroid', webViewJavascriptBridge);
					bridge = webViewJavascriptBridge; //保存起来以后别的页面用
					initiated(true)
				});
			}
		}
	}

	function throwError(text) {
		alert(text || failText)
		throw new Error(text || failText)
	}
	
	function judge(v, text) {
		if(!v) {
			throwError(text)
		}
	}
	
	function removeParams(params, keys) {
		keys.forEach(v => {
			if(params[v]) {
				delete params[v]
			}
		})
	}

	// 调用sdk方法
	let invokeNativeMethod = function(apiName, params, configs = {}) {
		const success = params.success || new Function()
		const fail = params.fail || new Function()
		
		const _cb = function() {
			if (isInWechatWV) { // wechatWV
				if(SDK_LOAD_STATUS == 'initialized'){
					
					bridge[apiName].call(null, params)
					
				}else if(SDK_LOAD_STATUS == 'failed' && configs.buildInWXMethods) { // sdk加载失败就直接跳页面去调jssdk
					judge(params.href, '缺少href参数')

					const { href, failHref} = params
					removeParams(params, ['fail','success','href','failHref'])
					
					const otherParams = Object.keys(params).length ? `&params=${encodeURIComponent(JSON.stringify(params))}` : ''
					bridge.miniProgram.navigateTo({
						url:`/pages/wechat/useWXMethod?href=${encodeURIComponent(href)}&failHref=${encodeURIComponent(failHref || href)}&method=${configs.buildInWXMethods}${otherParams}`
					})
				}
			} else { // superappWV
				removeParams(params, ['fail','success'])
				
				// bridge.callHandler('sysGetLocation', params, function(res) {
				// 	console.log('res'. res)
				// 	if (res.code == 0) {
				// 		success(res)
				// 	} else {
				// 		fail(res)
				// 	}
				// })
				bridge.callHandler(apiName, params, function(res) {
					if (res.code == 0) {
						success(res)
					} else {
						fail(res)
					}
				})
			}
		}

		// bridge已初始化成功 || 如果小程序内sdk加载失败那么使用备用方案 跳换页面去执行api
		if (SDK_LOAD_STATUS == 'initialized' || (SDK_LOAD_STATUS == 'failed' && isInWechatWV && configs.buildInWXMethods)) {
			_cb()
		} else if (SDK_LOAD_STATUS == 'uninitialized' || SDK_LOAD_STATUS == 'initializing') { // 正在初始化或未初始化
			queue.push(_cb)
			if (SDK_LOAD_STATUS == 'uninitialized') { // 未初始化
				bridgeInit(true, function(e) {
					fail(e)
				})
			}
		} else {
			throwError()
		}
	}

	/**
	 * 绑定微信配置
	 * @param {Array} jsApiList 需要使用的微信api列表
	 */
	function bindWeixinConfigs(jsApiList) {
		// portalServiceUrl 门户接口域名地址
		wxParams.portalServiceUrl = 'https://portal-service.xjmu.edu.cn'
		wxParams.jsApiList = jsApiList
	}

	/**
	 * 调用sdk的方法
	 */
	_global.invokeNativeMethod = invokeNativeMethod
	_global.invokeWechatMethod = invokeNativeMethod

	/**
	 * 加载debuger
	 */
	_global.loadVConsole = loadDebuger

	/**
	 * 绑定快捷方法
	 * @param {String} apiName
	 * @param {Object} params
	 */
	function basicBind(apiName, params, configs = {}) {
		if (!isInSuperappWV && !isInWechatWV) {
			throwError()
			return
		}

		// 小程序webview下需绑定必要的参数
		if (isInWechatWV) {
			bindWeixinConfigs([apiName])
		}

		invokeNativeMethod(apiName, params, configs)
	}

	/**
	 * 打开新的webview
	 */
	_global.superAppOpenNewWebview = function(params = {}) {
		basicBind("openNewWebview", params)
	}

	/**
	 * 获取环境
	 * @param {Function} callback
	 */
	_global.getENV = function(callback) {
		callback && callback({
			superappWV: isInSuperappWV,
			wechatWV: isInWechatWV,
			wechat: isWechat,
			ios: isIOS,
			android: isAndroid
		})
	}

	window.addEventListener('DOMContentLoaded', () => {
		// app提前加载sdk
		if (SDK_LOAD_STATUS == 'uninitialized' && isInSuperappWV) {
			bridgeInit(false)
		}
	}, false)

})((typeof module == 'object' && typeof module.exports == 'object') ? module.exports : window)
